<template>
  <section
    class="chartBox"
    :class="{
      chartBorder: chartConfig.chartBorder.width,
      chartBgColor:
        chartConfig.style.background.show &&
        chartConfig.style.background.fillType === 'color',
      chartBgImage:
        chartConfig.style.background.show &&
        chartConfig.style.background.fillType === 'image',
    }"
    :style="{
      '--borderWidth': chartConfig.chartBorder.width + 'px',
      '--borderColor': chartConfig.chartBorder.color,
      '--bgColor': chartConfig.style.background.color,
    }"
  >
    <div class="flex chartTitleBox justify-between">
      <div class="flex align-center margin-bottom-sm">
        <h4 class="title icon" v-show="chartConfig.chartTitle.show">
          {{ chartConfig.chartTitle.text }}
        </h4>
        <t-tooltip :content="chartConfig.chartTips.text">
          <component class="margin-left-sm" is="InfoCircleIcon" size="18" v-show="chartConfig.chartTips.show" />
        </t-tooltip>
      </div>
    </div>
    <div :id="id" :class="className" :style="{ height, width }" />
  </section>
</template>
<script setup lang="ts">
import {
  ref,
  reactive,
  onMounted,
  onBeforeUnmount,
  watch,
  nextTick,
  computed,
} from 'vue';
import * as echarts from 'echarts';
import 'echarts-wordcloud';
import 'echarts-liquidfill';
import worldJson from '@/assets/map/world.json';
import chinaJson from '@/assets/map/china.json';
import { storeToRefs } from 'pinia';
import { useSystemStore } from '@/store/modules/system';
import { chartParams } from '@/components/Chart/chartType';
import { isData_noDataset } from '@/views/chartManage/components/chartSettingShow';
import { chartTypeGroup } from '@/views/chartManage/components/chartName';
const storeSystem = useSystemStore();
const { themeConfig } = storeToRefs(storeSystem);
let myChart: echarts.ECharts;
const props = defineProps({
  id: {
    type: String,
    default: 'chart',
    required: true,
  },
  className: {
    type: String,
    default: '',
  },
  width: {
    type: String,
    default: '100%',
  },
  height: {
    type: String,
    default: '300px',
  },
  fullOptions: {
    type: Object,
    default: () => ({}),
    required: true,
  },
  fullData: {
    type: Object,
    default: () => ({}),
    required: true,
  },
});
let chartConfig = computed(() => {
  return props.fullOptions;
});
let chartData = ref(props.fullData);
// 图表配置项参数字段
let echartsOptions = ref({});
//重绘图表函数
const resizeHandler = () => {
  myChart.resize();
};
//设置防抖，保证无论拖动窗口大小，只执行一次获取浏览器宽高的方法
const debounce = (fun: { (): void; (): void }, delay: number | undefined) => {
  let timer: any;
  return function () {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      fun();
    }, delay);
  };
};
const cancalDebounce = debounce(resizeHandler, 50);
// 处理图表数据格式
let chartsData = reactive<any>({
  data: [],
  dimensions: [],
});
const transformData = () => {
  if (chartConfig.value.currentChartType) {
    // options配置使用的是dataset形式，两个参数data（图表的数据）和dimension（图表的维度）
    if (isData_noDataset.includes(chartTypeTitle.value)) {
      switch (chartConfig.value.currentChartType) {
        case 'wordCloud':
          const result = [];
          for (const key in chartData.value.lists[0]) {
            if (key !== 'name') {
              result.push({ name: key, value: chartData.value.lists[0][key] });
            }
          }
          chartsData.data = result;
          chartsData.dimensions = [];
          break;
        case 'boxplot':
          // 箱线图暂不启用
          chartsData.data = [
            {
              product: '测试数据1',
              '10-20': [120, 132, 101, 134, 90],
              '30-40': [120, 132, 101, 134, 90],
            },
            {
              product: '测试数据2',
              '10-20': [220, 182, 191, 234, 290],
              '30-40': [120, 132, 101, 134, 90],
            },
            {
              product: '测试数据3',
              '10-20': [150, 232, 201, 154, 190],
              '30-40': [120, 132, 101, 134, 90],
            },
            {
              product: '测试数据4',
              '10-20': [320, 332, 301, 334, 390],
              '30-40': [120, 132, 101, 134, 90],
            },
            {
              product: '测试数据5',
              '10-20': [232, 182, 101, 234, 150],
              '30-40': [120, 132, 101, 134, 90],
            },
          ];
          chartsData.dimensions = ['product', '10-20', '30-40'];
          break;
        case 'radar':
          const radarData = chartData.value.lists?.map((item: any) => ({
            name: item.name,
            value: Object.values(item).slice(1),
          }));
          chartsData.data = radarData;
          let radarIndex = ref<any>([]);
          for (const key in chartData.value.maxLists) {
            radarIndex.value.push({
              name: key,
              max: chartData.value.maxLists[key],
            });
            chartsData.dimensions = radarIndex.value;
          }
          break;
        case 'liquidFill':
          let sum: number[] = Object.values(chartData.value.lists[0]).filter(
            (num: any) => {
              return typeof num === 'number';
            },
          ) as number[];
          let max = 0;
          sum.map((res: number) => {
            max += res;
          });
          chartsData.data =
            (Object.values(chartData.value.lists[0])[1] as number) / max;
          chartsData.dimensions = [];
          break;
        case 'china':
          const mapData = [];
          if (chartData.value.lists) {
            for (const key in chartData.value.lists[0]) {
              if (key !== 'name') {
                mapData.push({
                  name: key,
                  value: chartData.value.lists[0][key],
                });
              }
            }
            chartsData.data = mapData;
            chartsData.dimensions = chartData.value.lists[0].name;
          }

          break;
        case 'world':
          const worldMapData = [];
          if (chartData.value.lists) {
            for (const key in chartData.value.lists[0]) {
              if (key !== 'name') {
                worldMapData.push({
                  name: key,
                  value: chartData.value.lists[0][key],
                });
              }
            }
            chartsData.data = worldMapData;
            chartsData.dimensions = chartData.value.lists[0].name;
          }

          break;
      }
    } else {
      chartsData.data = transformDataset(chartData.value);
      if (chartData.value.lists) {
        let chartName = chartData.value.lists.map((res: any) => {
          return res.name;
        });
        chartName.unshift('product');
        chartsData.dimensions = chartName;
      }
    }
  }
};
const transformDataset = (data: any) => {
  return data.x_data?.map((res: any) => {
    let chartItem = { product: res };
    
    data.lists.map((item: any) => {
      //@ts-ignore
      chartItem[item.name] = item[res];
    });
    return chartItem;
  });
};
const chartTypeTitle = computed(() => {
  let title = '';
  chartTypeGroup.map((res: any) => {
    res.children.map((child: any) => {
      if (child.url == chartConfig.value.currentChartType) {
        title = res.title;
      }
    });
  });
  return title;
});
//绘制图表
onMounted(() => {
  nextTick(() => {
    myChart = echarts.init(document.getElementById(props.id) as HTMLDivElement);
    //@ts-ignore
    echarts.registerMap('world', worldJson);
    echarts.registerMap('china', chinaJson as any);

    myChart.showLoading({
      text: '',
      color: '#409eff',
      textColor: '#000',
      maskColor: 'rgba(255, 255, 255, .95)',
      zlevel: 0,
      lineWidth: 2,
    });
    setChartOption();
    //自适应图表尺寸
    window.addEventListener('resize', cancalDebounce);
  });
});
const setChartOption = () => {
  myChart.hideLoading();
  if (chartData.value && chartConfig.value.currentChartType) {
    transformData();
    nextTick(() => {
      //@ts-ignore
      echartsOptions.value = chartParams[chartConfig.value.currentChartType](
        chartConfig.value.chartOption,
        chartsData.data ?? [],
        chartsData.dimensions,
      );
      myChart.setOption(echartsOptions.value, true);
    });
  }
};
//页面销毁前，销毁事件和实例
onBeforeUnmount(() => {
  window.removeEventListener('resize', cancalDebounce);
  myChart.dispose();
});
//监听图表数据时候变化，重新渲染图表
watch(
  () => [
    props.fullOptions,
    chartData.value,
    themeConfig.value.themeMode,
    themeConfig.value.themeColor,
  ],
  () => {
    nextTick(() => {
      setChartOption();
    });
  },
  { deep: true },
);
watch(
  () => props.fullData,
  newVal => {
    chartData.value = newVal;
  },
  { deep: true },
);
// 暴露给父组件使用
defineExpose({ resizeHandler });
</script>
<style lang="scss" scoped>
.chartBox {
  border-style: solid;
  border-color: transparent;
  border-width: 1px;
  padding: 12px;
  border-radius: 2px;
}

.chartBorder {
  border-color: var(--borderColor);
  border-width: var(--borderWidth);
}

.chartBgColor {
  background-color: var(--bgColor);
}

.chartBgImage {
  background-image: var(--bgImage);
  background-size: 100% 100%;
}

.chartTitleBox {
  height: 30px;
  overflow: hidden;
}

.chartMore {
  border: 1px solid;
  @include border_color('border_color');
  padding: 2px;
  cursor: pointer;
}

.chartIndexGroup {
  box-sizing: border-box;

  > li {
    .label {
      color: var(--labelColor);
      font-size: var(--labelSize);
    }

    .number {
      color: var(--numberColor);
      font-size: var(--numberSize);
    }

    .chartIndex {
      margin-left: 12px;
      display: flex;
      flex-direction: column;
      gap: 10px;

      &.rightBorder {
        text-align: center;
        margin: 12px 0;
        border-right: 1px solid;
        @include border_color('border_color');
      }

      &.indexChart3 {
        .number {
          @include background_color('background_color');
          padding: 0 5px;
        }
      }

      .chain {
        margin-top: 10px;
        display: flex;
        align-items: center;
        gap: 8px;

        .chainText {
          @include font_color('placeholder_color');
        }

        .chainIndex {
          .t-icon {
            @include background_color('background_color');
            border-radius: 50%;
            padding: 3px;
            font-size: 18px;

            &.t-icon-arrow-up {
              @include font_color('error_color');

              + span {
                @include font_color('error_color');
              }
            }

            &.t-icon-arrow-down {
              @include font_color('success_color');

              + span {
                @include font_color('success_color');
              }
            }
          }
        }
      }
    }

    .indexChart6 {
      display: flex;
      align-items: center;
      justify-content: space-between;
      width: 100%;
    }

    .indexSet1 {
      display: flex;
      align-items: center;
      justify-content: space-between;
      width: 100%;
    }

    .indexSet3 {
      display: flex;
      align-items: center;
      justify-content: space-around;
      width: 100%;
      padding-bottom: 8px;

      &:nth-of-type(1) {
        border-bottom: 1px solid;
        border-color: var(--borderColor);
      }
    }
  }
}
</style>
